home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / DEMO_VGA / FRSTM1.LZH / XBIT.C < prev    next >
C/C++ Source or Header  |  1989-03-25  |  3KB  |  118 lines

  1. /* Xbit.c by Mark C. Peterson, CompuServe [70441,3353] */
  2.  
  3. #include <string.h>
  4. #include <malloc.h>
  5. #include "xbit.h"
  6.  
  7. int 
  8.    XBits, XBytes, IntXBits, DecXBits, ParDecXBits, ParDecXBytes,
  9.    MultShiftBits, MultBytes, XBitOverflow, XBitSign;
  10.  
  11. void SetXBit(int Bytes, int IntBits) {
  12.    XBytes = Bytes + 1;
  13.    XBytes >>= 1;
  14.    XBytes <<= 1;
  15.    XBits = Bytes << 3;
  16.    IntXBits = IntBits;
  17.    DecXBits = XBits - (IntBits + 1);
  18.    ParDecXBytes = DecXBits >> 3;
  19.    ParDecXBits = DecXBits & 7;
  20.    MultBytes = IntBits >> 3;
  21.    MultShiftBits = IntBits & 7;
  22. }
  23.  
  24. int DoubleToXBit(double d, XBIT x) {
  25.    char Signed, dc[10];
  26.    int *di, Underflow;
  27.  
  28.    /* 1.  Setup integer alias */
  29.    di = (int*)dc;
  30.  
  31.    /* 2.  Clear 'x' */
  32.    strnset(x, 0, XBytes);
  33.  
  34.    /* 3.  Copy 'd' to char buffer */
  35.    memcpy(&dc[2], (char*)&d, 8);
  36.    di[0] = 0;
  37.  
  38.    /* 4.  Get and mask the sign bit */
  39.    Signed = dc[9] &0x80;
  40.    dc[9] &= 0x7f;
  41.  
  42.    /* 5.  Separate exponent from mantisa */
  43.    XBitShift(dc, 10, -4);
  44.  
  45.    /* 6.  Check for double = 0 (i.e. exponent = 0) */
  46.    if(!di[4])
  47.       return(0);
  48.  
  49.    /* 7.  Convert negative biased mantisa (ranged from 1.0 to 2.0) 
  50.           and make room for sign bit */
  51.    XBitShift(dc, 8, -2);
  52.    dc[7] |= 0x40;
  53.  
  54.    /* 8.  Convert excess 1023 exponent to deficit 'IntXBits - 1' */
  55.    di[4] -= 1023 + (XBits - DecXBits - 2);
  56.  
  57.    /* 9.  Check for Overflow */
  58.    if(di[4] > 0)
  59.       return(di[4]);
  60.  
  61.    /* 10. Check for Underflow */
  62.    Underflow = di[4] + XBits;
  63.    if(Underflow < 0)
  64.       return(Underflow);
  65.  
  66.    /* 11. Move mantisa to 'x' */
  67.    if(XBytes >= 8)
  68.       memcpy(&x[XBytes - 8], dc, 8);
  69.    else
  70.       memcpy(x, &dc[8 - XBytes], XBytes);
  71.  
  72.    /* 12. Right bit shift 'x' by exponent */
  73.    XBitShift(x, XBytes, di[4]);
  74.  
  75.    /* 13. Negate 'x' if 'd' was signed */
  76.    if(Signed)
  77.       return(XBitNegate(x, XBytes));
  78.    else
  79.       return(0);
  80. }
  81.  
  82. /* Not used by Malderbot draw program, but helps out in debugging */
  83.  
  84. double XBitToDouble(XBIT XBit) {
  85.    char *dc, *x;
  86.    double d = 0.0;
  87.    int Exponent, *di;
  88.    unsigned Sign;
  89.  
  90.    dc = (char*)&d;
  91.    di = (int*)dc;
  92.    x = malloc(XBytes);
  93.    memcpy(x, XBit, XBytes);
  94.    if(x[XBytes - 1] < 0) {
  95.       XBitNegate(x, XBytes);
  96.       Sign = 0x8000;
  97.    }
  98.    else
  99.       Sign = 0;
  100.    for(Exponent = 0; Exponent < XBits; Exponent++) {
  101.       if(XBitShift(x, XBytes, 1)) {
  102.          if(XBytes >= 8) {
  103.             XBitShift(x, XBytes, -4);
  104.             memcpy(dc, &x[XBytes - 8], 7);
  105.          }
  106.          else {
  107.             memcpy(&dc[7 - XBytes], x, XBytes);
  108.             XBitShift(dc, 7, -4);
  109.          }
  110.          Exponent = 1023 + (IntXBits - Exponent);
  111.          di[3] |= (Exponent << 4) | Sign;
  112.       }
  113.    }
  114.    free(x);
  115.    return(d);
  116. }
  117.  
  118.